package sample4.provider.dml;

import java.util.ArrayList;
import java.util.List;

import android.content.ContentResolver;
import android.content.Context;
import android.content.CursorLoader;
import android.database.Cursor;
import android.net.Uri;

/**
 * <pre>
 * ...
 * SqliteQueryBuilder sql = new SqliteQueryBuilder(uri);
 * sql.addProjection("columnName");
 * sql.whereAndEquals("_id", 10);
 * sql.addSortOrder("_id");
 * sql.setLimit(10);
 * sql.setOffset(100);
 * Cursor cursor = sql.query(getContentResolver());
 * ...
 * </pre>
 */
public class SqliteQueryBuilder extends AbsDmlBuilder {
    private List<String> mProjections = new ArrayList<String>();
    private List<String> mSortOrders = new ArrayList<String>();
    private int mLimit;
    private int mOffset;

    /**
     * コンストラクタ
     * 
     * @param uri query対象
     */
    public SqliteQueryBuilder(Uri uri) {
        super(uri);
    }

    /**
     * 引っ張ってくる対象カラムを設定する
     * 
     * @param projection カラム名
     */
    public void addProjection(String projection) {
        mProjections.add(projection);
    }

    /**
     * 並び替えを設定する
     * 
     * @param sortOrder カラム名
     */
    public void addSortOrder(String sortOrder) {
        mSortOrders.add(sortOrder);
    }

    /**
     * 並び替えを設定する(逆順)
     * 
     * @param sortOrder カラム名
     */
    public void addSortOrderDesc(String sortOrder) {
        addSortOrder(sortOrder + " DESC ");
    }

    /**
     * 引っ張ってくる最大件数を設定する
     * 
     * @param limit 最大件数
     */
    public void setLimit(int limit) {
        mLimit = limit;
    }

    /**
     * 引っ張ってくるレコードのOffsetを設定する
     * 
     * @param offset
     */
    public void setOffset(int offset) {
        mOffset = offset;
    }

    /**
     * 引っ張ってくるOffsetと最大件数を設定する
     * 
     * @param limit 最大件数
     * @param offset
     */
    public void setLimitOffset(int limit, int offset) {
        setLimit(limit);
        setOffset(offset);
    }

    /**
     * カーソルを取得する
     * 
     * @param contentResolver
     * @return カーソル
     */
    public Cursor query(ContentResolver contentResolver) {
        return contentResolver.query(mUri, getProjection(), getSelection(), getSelectionArgs(), getSortOrder());
    }

    /**
     * カーソルローダを取得する
     * 
     * @param context
     * @return　CursorLoader
     */
    public CursorLoader cursorLoader(Context context) {
        return new CursorLoader(context, mUri, getProjection(), getSelection(), getSelectionArgs(), getSortOrder());
    }

    private String[] getProjection() {
        String[] projection = null;
        // SELECTION ~
        if (!mProjections.isEmpty()) {
            projection = mProjections.toArray(new String[] {});
        }
        return projection;
    }

    private String getSelection() {
        // WHERE ~ AND ~
        return getWhere();
    }

    private String[] getSelectionArgs() {
        // WHERE ~ AND ~
        return getWhereArgs();
    }

    private String getSortOrder() {
        String sortOrder = null;
        // ORDER BY ~
        if (!mSortOrders.isEmpty()) {
            StringBuilder sb = new StringBuilder();
            int len = mSortOrders.size();
            for (int i = 0; i < len; i++) {
                // sortOrder
                sb.append(mSortOrders.get(i));
                // add comma
                if (i < len - 1) {
                    sb.append(", ");
                }

            }
            sortOrder = sb.toString();
        }

        // LIMIT ~ OFFSET ~
        if (0 < mLimit) {
            // add limit
            sortOrder += " LIMIT " + mLimit + " OFFSET " + mOffset;
        }
        return sortOrder;
    }
}
